# -*- coding: utf-8 -*-
# 高频策略
import traceback
import numpy as np
from tool.gongju import *
from tool.zhibiao import ma_z


def gaopincelue_v3(cl_sj):
    """
    开仓逻辑：
    多：价格突破60个tick的低点，且当前持仓量减上一tick持仓量的绝对值大于nn1，且n*2倍的tick范围内上涨超过n跳（对价开多），
    平仓逻辑：
    止盈：开仓成交后直接挂5跳止盈。
    止损：反向3跳对价止盈
    收盘清仓： 在小节收盘都需平仓
    空开仓逻辑反之
    """
    # 数据初始化，
    Datetime = cl_sj.klines[0].datetime.values
    # Close = cl_sj.klines[0].close.values
    Open = cl_sj.klines[0].open.values
    # High = cl_sj.klines[0].high.values
    # Low = cl_sj.klines[0].low.values
    # volume = cl_sj.klines[0].volume.values
    canshu = [cl_sj.jiaoyiqidong, cl_sj.zhanghu, cl_sj.jiaoyishezhi, cl_sj.openingdata, Datetime]  # 传递给交易函数用于交易
    chicang = cl_sj.openingdata['kaicangzhuangtai']
    chicangshuliang = cl_sj.openingdata['kaicangshuliang'] * chicang
    shijian = int(time_to_datetime(Datetime[-1]).time().strftime("%H%M%S"))  # 当前时间
    zhbh = cl_sj.jiaoyishezhi[0][0]  # 开仓账户编号

    # 参数设置区
    ss = cl_sj.jiaoyishezhi[5][0]  # 初次开仓数量
    zy = cl_sj.jiaoyishezhi[5][1]  # 第一次挂单止盈价
    zs = cl_sj.jiaoyishezhi[5][2]  # 止损
    zdfzq = cl_sj.jiaoyishezhi[5][3]  # 涨跌幅周期
    zdf = cl_sj.jiaoyishezhi[5][4]  # 快速涨跌幅
    qingcangshijian = [101000, 112500, 145500, 225500]  # 清仓时间
    cckcbz = 0  # 初次开仓标志，为1为有条件开仓

    if 'hydx' not in cl_sj.sjb:  # 初始化时执行一次，用于初始化缓存字典
        cl_sj.sjb['hydx'] = cl_sj.zhanghu[zhbh].get_zuixiaobiandong(cl_sj.jiaoyishezhi[3][0])   # 最小变动单位
        cl_sj.sjb['cczt'] = 0  # 持仓状态
        cl_sj.sjb['xdid_zy'] = '8888'  # 止盈挂单id
        cl_sj.sjb['xdid_zs'] = '8888'  # 止盈挂单id
        cl_sj.sjb['xdid_ccxd'] = '8888'  # 初次挂单id
        cl_sj.sjb['高点'] = 0
        cl_sj.sjb['低点'] = 0
        cl_sj.sjb['止盈挂单价'] = 0
        cl_sj.sjb['止盈挂单标志'] = True
        cl_sj.sjb['止盈成交标记'] = False
        cl_sj.sjb['涨跌幅'] = 0
        cl_sj.sjb['开仓时涨跌幅'] = 0
        cl_sj.sjb['买价'] = []
        cl_sj.sjb['卖价'] = []
        cl_sj.sjb['最新价'] = []
        cl_sj.sjb['持仓量'] = []

    zy = zy * cl_sj.sjb['hydx']
    zs = zs * cl_sj.sjb['hydx']
    # zdf = zdf * cl_sj.sjb['hydx']
    ccwtpy = 2*cl_sj.sjb['hydx']  # 出场委托偏移
    cdpy = 5*cl_sj.sjb['hydx']  # 向不利方向移动2跳测单

    cl_sj.sjb['买价'].append(cl_sj.tick['Bids'][0][0])  # 买价
    cl_sj.sjb['卖价'].append(cl_sj.tick['Asks'][0][0])  # 卖价
    cl_sj.sjb['最新价'].append(cl_sj.tick['LastPrice'])
    cl_sj.sjb['持仓量'].append(cl_sj.tick['OpenInterest'])
    if len(cl_sj.sjb['卖价']) > 60:
        cl_sj.sjb['买价'] = cl_sj.sjb['买价'][-60:]
        cl_sj.sjb['卖价'] = cl_sj.sjb['卖价'][-60:]
        cl_sj.sjb['最新价'] = cl_sj.sjb['最新价'][-60:]
        cl_sj.sjb['持仓量'] = cl_sj.sjb['持仓量'][-60:]

    # if cl_sj.shangcishijian != Datetime[-1]:
    #     # DKX计算
    #     pass

    ccss = (chazhaoheyue_duiyingchicang(cl_sj.zhanghu[zhbh].df_cc, cl_sj.jiaoyishezhi[3][0]))[0]
    # 账户持仓放入显示
    if ccss != chicangshuliang:
        MubiaoCangwei4_bxd(ccss, Open[-1], canshu)

    if cl_sj.jiaoyiqidong:  # 更新k线时执行，一般用与计算指标 ，允许交易 cl_sj.shangcishijian != datetime[-1] and
        yunxukaicang = (shijian > 90300 and shijian < 101300) or (shijian > 210300 and shijian < 235950) or \
                       (shijian > 103100 and shijian < 112800) or (shijian > 133300 and shijian < 145800)   # 允许开仓时间
        # 初次开仓
        if yunxukaicang and len(cl_sj.sjb['卖价']) > 58:
            # 开多
            cl_sj.sjb['高点'] = max(cl_sj.sjb['最新价'][:-1])
            cl_sj.sjb['低点'] = min(cl_sj.sjb['最新价'][:-1])
            cl_sj.sjb['涨跌幅'] = round((cl_sj.sjb['最新价'][-1] - cl_sj.sjb['最新价'][-zdfzq])/cl_sj.sjb['最新价'][-1]*100,3)
            if cl_sj.sjb['cczt'] == 0:
                if cl_sj.sjb['最新价'][-1] > cl_sj.sjb['高点'] and cl_sj.sjb['涨跌幅'] > zdf:  # 满足初次开多条件
                    cl_sj.sjb['开仓价'] = cl_sj.sjb['买价'][-1] + ccwtpy  # 取排队价
                    cl_sj.jiaoyishezhi[8][3] = cl_sj.sjb['开仓价']
                    cl_sj.sjb['xdid_ccxd'] = cl_sj.zhanghu[zhbh].kc_orders(cl_sj.jiaoyishezhi, 1, ss)  # 开多
                    print('初次开多=', cl_sj.jiaoyishezhi[3][0], cl_sj.sjb['开仓价'], ss)
                    cl_sj.sjb['止盈挂单价'] = cl_sj.sjb['开仓价'] + zy  # 第一次止盈挂单价
                    cl_sj.sjb['开仓时涨跌幅'] = cl_sj.sjb['涨跌幅']
                    cl_sj.sjb['cczt'] = 1
                    cl_sj.sjb['止盈挂单标志'] = True
                    cl_sj.sjb['止盈成交标记'] = False
                    cckcbz = 1

                else:  # 开空
                    if cl_sj.sjb['最新价'][-1] < cl_sj.sjb['低点'] and cl_sj.sjb['涨跌幅'] < -zdf:  # 满足初次开多条件
                        cl_sj.sjb['开仓价'] = cl_sj.sjb['卖价'][-1] - ccwtpy  # 取排队价
                        cl_sj.jiaoyishezhi[8][3] = cl_sj.sjb['开仓价']
                        cl_sj.sjb['xdid_ccxd'] = cl_sj.zhanghu[zhbh].kc_orders(cl_sj.jiaoyishezhi, -1, ss)  # 开多
                        print('初次开空=', cl_sj.jiaoyishezhi[3][0], cl_sj.sjb['开仓价'], ss)
                        cl_sj.sjb['止盈挂单价'] = cl_sj.sjb['开仓价'] - zy  # 第一次止盈挂单价
                        cl_sj.sjb['开仓时涨跌幅'] = cl_sj.sjb['涨跌幅']
                        cl_sj.sjb['cczt'] = -1
                        cl_sj.sjb['止盈挂单标志'] = True
                        cl_sj.sjb['止盈成交标记'] = False
                        cckcbz = 1

        # 账户仓位数据获取
        if cckcbz == 1:  # 有次仓条件开仓着暂停下，等待仓位返回
            time.sleep(0.3)

        # 第一次挂单止盈
        if cl_sj.sjb['cczt'] == 1:
            if ccss == ss and cl_sj.sjb['止盈挂单标志']:  # 挂多单止盈
                if cl_sj.sjb['xdid_ccxd'] in cl_sj.zhanghu[zhbh].order_dict:  # 已进行止盈挂单
                    if cl_sj.zhanghu[zhbh].order_dict[cl_sj.sjb['xdid_ccxd']]['kcdsl'] == 0:  # 可撤单数量为0
                        cl_sj.jiaoyishezhi[8][3] = cl_sj.sjb['止盈挂单价']  # 多止盈挂单价格
                        cl_sj.sjb['xdid_zy'] = cl_sj.zhanghu[zhbh].pc_orders(cl_sj.jiaoyishezhi, 1, ss)  # 多止盈平仓挂单
                        cl_sj.sjb['止盈挂单标志'] = False
                        cl_sj.sjb['止盈成交标记'] = True
                        print('止盈挂单多=', cl_sj.jiaoyishezhi[3][0], cl_sj.sjb['止盈挂单价'], ss)
            else:
                if cl_sj.sjb['xdid_ccxd'] in cl_sj.zhanghu[zhbh].order_dict and cl_sj.sjb['止盈挂单标志']:  # 已进行止盈挂单
                    if cl_sj.zhanghu[zhbh].order_dict[cl_sj.sjb['xdid_ccxd']]['kcdsl'] != 0:  # 可撤单数量不等于0
                        if cl_sj.sjb['涨跌幅'] < zdf:  # 价格小于快速涨跌幅
                            cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_ccxd'])
                            time.sleep(0.3)
                            cl_sj.sjb['cczt'] = 0
                            print("不成交撤单多")

        ccss2 = abs(ccss)
        if cl_sj.sjb['cczt'] == -1:
            if ccss2 == ss and cl_sj.sjb['止盈挂单标志']:  # 挂空单
                if cl_sj.sjb['xdid_ccxd'] in cl_sj.zhanghu[zhbh].order_dict:  # 已进行止盈挂单
                    if cl_sj.zhanghu[zhbh].order_dict[cl_sj.sjb['xdid_ccxd']]['kcdsl'] == 0:  # 可撤单数量为0
                        cl_sj.jiaoyishezhi[8][3] = cl_sj.sjb['止盈挂单价']  # 多止盈挂单价格
                        cl_sj.sjb['xdid_zy'] = cl_sj.zhanghu[zhbh].pc_orders(cl_sj.jiaoyishezhi, -1, ss)  # 空止盈平仓挂单
                        cl_sj.sjb['止盈挂单标志'] = False
                        cl_sj.sjb['止盈成交标记'] = True
                        print('止盈挂单空=', cl_sj.jiaoyishezhi[3][0], cl_sj.sjb['止盈挂单价'], ss)
                else:
                    if cl_sj.sjb['xdid_ccxd'] in cl_sj.zhanghu[zhbh].order_dict and cl_sj.sjb['止盈挂单标志']:  # 已进行止盈挂单
                        if cl_sj.zhanghu[zhbh].order_dict[cl_sj.sjb['xdid_ccxd']]['kcdsl'] == 0:  # 可撤单数量不等于0
                            if cl_sj.sjb['涨跌幅'] > -zdf:  # 价格小于快速涨跌幅
                                cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_ccxd'])
                                time.sleep(0.3)
                                cl_sj.sjb['cczt'] = 0
                                print("不成交撤单空")

        if ccss == 0 and cl_sj.sjb['止盈成交标记']:  # 止盈成交后状态置零
            cl_sj.sjb['cczt'] = 0
            cl_sj.sjb['止盈成交标记'] = False

        # 止损
        if ccss > 0 and cl_sj.sjb['cczt'] == 1:  # 多止损
            if cl_sj.sjb['开仓价']-cl_sj.sjb['最新价'][-1] > zs:
                cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_zy'])
                time.sleep(0.3)
                cl_sj.jiaoyishezhi[8][3] = cl_sj.sjb['卖价'][-1] - cdpy  # 止损价格
                cl_sj.sjb['xdid_zs'] = cl_sj.zhanghu[zhbh].pc_orders(cl_sj.jiaoyishezhi, 1, ccss)
                cl_sj.sjb['cczt'] = 0  # 开仓状态清0
                print('多单止损=', cl_sj.jiaoyishezhi[3][0], cl_sj.sjb['卖价'][-1], ccss)
        else:
            if ccss < 0 and cl_sj.sjb['cczt'] == -1:  # 空止损
                if cl_sj.sjb['最新价'][-1]-cl_sj.sjb['开仓价'] > zs:
                    cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_zy'])
                    time.sleep(0.3)
                    cl_sj.jiaoyishezhi[8][3] = cl_sj.sjb['买价'][-1] + cdpy  # 止损价格
                    cl_sj.sjb['xdid_zs'] = cl_sj.zhanghu[zhbh].pc_orders(cl_sj.jiaoyishezhi, -1, abs(ccss))
                    cl_sj.sjb['cczt'] = 0  # 开仓状态清0
                    print('空单止损=', cl_sj.jiaoyishezhi[3][0], cl_sj.sjb['买价'][-1], abs(ccss))

        # 收盘清仓
        if shijian in qingcangshijian:  # 等于清仓时间
            if ccss > 0 and cl_sj.sjb['cczt'] == 1:  # 多止损
                cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_zy'])
                cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_zs'])
                time.sleep(0.3)
                cl_sj.jiaoyishezhi[8][3] = cl_sj.tick['LastPrice'] - cdpy  # 止损价格
                cl_sj.zhanghu[zhbh].pc_orders(cl_sj.jiaoyishezhi, 1, ccss)
                cl_sj.sjb['cczt'] = 0  # 开仓状态清0
                print('收盘清仓多=', cl_sj.jiaoyishezhi[3][0], cl_sj.tick['LastPrice'] - ccwtpy, ccss)

            else:
                if ccss < 0 and cl_sj.sjb['cczt'] == -1:  # 空止损
                    cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_zy'])
                    cl_sj.zhanghu[zhbh].cd_orders(cl_sj.sjb['xdid_zs'])
                    time.sleep(0.3)
                    cl_sj.jiaoyishezhi[8][3] = cl_sj.tick['LastPrice'] + cdpy  # 止损价格
                    cl_sj.zhanghu[zhbh].pc_orders(cl_sj.jiaoyishezhi, -1, abs(ccss))
                    cl_sj.sjb['cczt'] = 0  # 开仓状态清0
                    print('收盘清仓空=', cl_sj.jiaoyishezhi[3][0], cl_sj.tick['LastPrice'] + ccwtpy, abs(ccss))

    return cl_sj.sjb['开仓时涨跌幅'], cl_sj.sjb['hydx'], cl_sj.sjb['最新价'][-1], cl_sj.sjb['涨跌幅']

